home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / editors / emacs / xemacs / xemacs-1.004 / xemacs-1 / xemacs-19.13 / src / specifier.h < prev    next >
Encoding:
C/C++ Source or Header  |  1995-06-29  |  10.3 KB  |  289 lines

  1. /* Generic specifier list implementation
  2.    Copyright (C) 1994, 1995 Board of Trustees, University of Illinois
  3.    Copyright (C) 1995 Ben Wing
  4.  
  5. This file is part of XEmacs.
  6.  
  7. XEmacs is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. XEmacs is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with XEmacs; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* Synched up with: Not in FSF. */
  22.  
  23. #ifndef _XEMACS_SPECIFIER_H_
  24. #define _XEMACS_SPECIFIER_H_
  25.  
  26. struct specifier_methods
  27. {
  28.   CONST char *name;
  29.   Lisp_Object predicate_symbol;
  30.  
  31.   /* Implementation specific methods: */
  32.  
  33.   /* #### Document me */
  34.   /* Create method */
  35.   void (*create_method) (Lisp_Object specifier);
  36.   /* Mark method */
  37.   void (*mark_method) (Lisp_Object specifier, void (*markobj) (Lisp_Object));
  38.   /* Equal method */
  39.   int (*equal_method) (Lisp_Object sp1, Lisp_Object sp2, int depth);
  40.   /* Hash method */
  41.   unsigned long (*hash_method) (Lisp_Object specifier, int depth);
  42.  
  43.   /* Validate method: Given an instantiator, return non-zero if it's
  44.      valid for this specifier type, zero otherwise.  If NO_ERROR
  45.      is zero, the validation method can signal an error if the
  46.      instantiator is invalid. (This is so that a more explanatory
  47.      error message can be issued.) Even if NO_ERROR is zero,
  48.      however, this function can go ahead and return 0 for an
  49.      invalid instantiator. (In that case, the caller gets a generic
  50.      error message "Invalid instantiator".) If this functions is not
  51.      present, all instantiators are considered valid. */
  52.   int (*validate_method) (Lisp_Object instantiator, int no_error);
  53.  
  54.   /* Instantiate method */
  55.   Lisp_Object (*instantiate_method) (Lisp_Object specifier,
  56.                      Lisp_Object domain,
  57.                      Lisp_Object instantiator,
  58.                      int no_error_or_quit);
  59.   /* Going-to-add method: Called when an instantiator is about
  60.      to be added to a specifier.  This function can specify
  61.      that different instantiators should be used instead by
  62.      returning an inst-list (possibly containing zero elements).
  63.      If the instantiator is fine as-is, return Qt.  The
  64.      instantiator has been copied with copy-tree, so feel
  65.      free to reuse parts of it to create a new instantiator.
  66.      The tag-set, however, is not copied and is not canonicalized
  67.      (that will be done on the result of this function).
  68.      */
  69.   Lisp_Object (*going_to_add_method) (Lisp_Object specifier,
  70.                       Lisp_Object locale,
  71.                       Lisp_Object tag_set,
  72.                       Lisp_Object instantiator);
  73.   /* After-change method */
  74.   void (*after_change_method) (Lisp_Object specifier,
  75.                    Lisp_Object locale);
  76.  
  77.   int extra_data_size;
  78. };
  79.  
  80. struct Lisp_Specifier
  81. {
  82.   struct lcrecord_header header;
  83.   struct specifier_methods *methods;
  84.  
  85.   /* we keep a chained list of all current specifiers, for GC cleanup
  86.      purposes.  Do NOT mark through this, or specifiers will never
  87.      be GC'd. */
  88.   Lisp_Object next_specifier;
  89.  
  90.   /* This is a straight list of instantiators. */
  91.   Lisp_Object global_specs;
  92.  
  93.   /* These are all assoc lists where the key is type of object the
  94.      list represents (buffer, window, etc.) and the associated list is
  95.      the actual list of instantiators. */
  96.   Lisp_Object device_specs;
  97.   Lisp_Object frame_specs;
  98.   Lisp_Object window_specs;
  99.   Lisp_Object buffer_specs;
  100.  
  101.   struct specifier_caching *caching;
  102.   Lisp_Object fallback;
  103.   /* type-specific extra data attached to a specifier */
  104.   char data[1];
  105. };
  106.  
  107. DECLARE_LRECORD (specifier, struct Lisp_Specifier);
  108. #define XSPECIFIER(x) XRECORD (x, specifier, struct Lisp_Specifier)
  109. #define XSETSPECIFIER(x, p) XSETRECORD (x, p, specifier)
  110. #define SPECIFIERP(x) RECORDP (x, specifier)
  111. #define CHECK_SPECIFIER(x, i) CHECK_RECORD (x, specifier)
  112.  
  113. /***** Calling a specifier method *****/
  114.  
  115. #define HAS_SPECMETH_P(sp, m) ((sp)->methods->m##_method)
  116. #define SPECMETH(sp, m, args) (((sp)->methods->m##_method) args)
  117.  
  118. /* Call a void-returning specifier method, if it exists */
  119. #define MAYBE_SPECMETH(sp, m, args)                \
  120. do {                                \
  121.   struct Lisp_Specifier *_maybe_specmeth_sp = (sp);        \
  122.   if (HAS_SPECMETH_P (_maybe_specmeth_sp, m))            \
  123.     SPECMETH (_maybe_specmeth_sp, m, args);            \
  124. } while (0)
  125.  
  126. MAC_DECLARE_EXTERN (struct Lisp_Specifier *, mactemp_specmeth_or_given)
  127.  
  128. /* Call a specifier method, if it exists; otherwise return
  129.    the specified value */
  130.  
  131. #define SPECMETH_OR_GIVEN(sp, m, args, given)                \
  132. MAC_BEGIN                                \
  133.   MAC_DECLARE (struct Lisp_Specifier *, mactemp_specmeth_or_given, sp)    \
  134.   HAS_SPECMETH_P (mactemp_specmeth_or_given, m) ?            \
  135.     SPECMETH (mactemp_specmeth_or_given, m, args) : (given)        \
  136. MAC_END
  137.  
  138. /***** Defining new specifier types *****/
  139.  
  140. #define DECLARE_SPECIFIER_TYPE(type)                \
  141. extern struct specifier_methods * type##_specifier_methods
  142.  
  143. #define DEFINE_SPECIFIER_TYPE(type)            \
  144. struct specifier_methods * type##_specifier_methods
  145.  
  146. #define INITIALIZE_SPECIFIER_TYPE(type, obj_name, pred_sym)        \
  147.   do {                                    \
  148.     type##_specifier_methods =                        \
  149.       malloc_type_and_zero (struct specifier_methods);            \
  150.     type##_specifier_methods->name = obj_name;                \
  151.     defsymbol (&type##_specifier_methods->predicate_symbol,        \
  152.            pred_sym);                        \
  153.     add_entry_to_specifier_type_list (Q##type,                \
  154.                       type##_specifier_methods);    \
  155.   } while (0)                                \
  156.  
  157. #define INITIALIZE_SPECIFIER_TYPE_WITH_DATA(type, obj_name, pred_sym)    \
  158.   do {                                    \
  159.     INITIALIZE_SPECIFIER_TYPE (type, obj_name, pred_sym);        \
  160.     type##_specifier_methods->extra_data_size =                \
  161.       sizeof (struct type##_specifier);                    \
  162.   } while (0)
  163.  
  164. /* Declare that specifier-type TYPE has method M; used in
  165.    initialization routines */
  166. #define SPECIFIER_HAS_METHOD(type, m) \
  167.   (type##_specifier_methods->m##_method = type##_##m)
  168.  
  169. /***** Macros for accessing specifier types *****/
  170.  
  171. #define SPECIFIER_IS_TYPE(sp, type)                    \
  172.   ((sp)->methods == type##_specifier_methods)
  173.  
  174. #ifdef ERROR_CHECK_TYPECHECK
  175. MAC_DECLARE_EXTERN (struct Lisp_Specifier *, mactemp_specifier_data)
  176. # define SPECIFIER_TYPE_DATA(sp, type)                    \
  177. MAC_BEGIN                                \
  178.   MAC_DECLARE (struct Lisp_Specifier *, mactemp_specifier_data, sp)    \
  179.   assert (SPECIFIER_IS_TYPE (mactemp_specifier_data, type))        \
  180.   MAC_SEP                                \
  181.   (struct type##_specifier *) mactemp_specifier_data->data        \
  182. MAC_END
  183. #else
  184. # define SPECIFIER_TYPE_DATA(sp, type)                    \
  185.   ((struct type##_specifier *) (sp)->data)
  186. #endif
  187.  
  188. /* #### Need to create ERROR_CHECKING versions of these. */
  189.  
  190. #define XSPECIFIER_TYPE(x, type) XSPECIFIER (x)
  191. #define XSETSPECIFIER_TYPE(x, p, type) XSETSPECIFIER (x, p)
  192. #define SPECIFIER_TYPEP(x, type)                \
  193.   (SPECIFIERP (x) && SPECIFIER_IS_TYPE (XSPECIFIER (x), type))
  194. #define CHECK_SPECIFIER_TYPE(x, i, type)            \
  195.   do {                                \
  196.     CHECK_SPECIFIER (x, i);                    \
  197.     if (!(SPECIFIERP (x) && SPECIFIER_IS_TYPE (XSPECIFIER (x),    \
  198.                            type)))        \
  199.       x = wrong_type_argument                    \
  200.     (type##_specifier_methods->predicate_symbol, x);    \
  201.   } while (0)
  202.  
  203. /***** Miscellaneous structures *****/
  204.  
  205. enum spec_locale_type
  206. {
  207.   LOCALE_GLOBAL,
  208.   LOCALE_DEVICE,
  209.   LOCALE_FRAME,
  210.   LOCALE_WINDOW,
  211.   LOCALE_BUFFER
  212. };
  213.  
  214. enum spec_add_meth
  215. {
  216.   SPEC_PREPEND,
  217.   SPEC_APPEND,
  218.   SPEC_REMOVE_TAG_SET_PREPEND,
  219.   SPEC_REMOVE_TAG_SET_APPEND,
  220.   SPEC_REMOVE_LOCALE,
  221.   SPEC_REMOVE_LOCALE_TYPE,
  222.   SPEC_REMOVE_ALL
  223. };
  224.  
  225. struct specifier_caching
  226. {
  227.   int offset_into_struct_window;
  228.   void (*value_changed_in_window) (Lisp_Object specifier, struct window *w,
  229.                    Lisp_Object oldval);
  230.   int offset_into_struct_frame;
  231.   void (*value_changed_in_frame) (Lisp_Object specifier, struct frame *f,
  232.                   Lisp_Object oldval);
  233. };
  234.  
  235. extern Lisp_Object decode_locale (Lisp_Object locale);
  236. extern Lisp_Object decode_locale_list (Lisp_Object locale);
  237. extern Lisp_Object decode_domain (Lisp_Object domain);
  238. extern enum spec_add_meth
  239.   decode_how_to_add_specification (Lisp_Object how_to_add);
  240. extern Lisp_Object decode_specifier_tag_set (Lisp_Object tag_set);
  241.  
  242. extern void add_entry_to_specifier_type_list (Lisp_Object symbol,
  243.                           struct specifier_methods *meths);
  244. extern void set_specifier_caching (Lisp_Object specifier,
  245.                    int struct_window_offset,
  246.                    void (*value_changed_in_window)
  247.                    (Lisp_Object specifier, struct window *w,
  248.                     Lisp_Object oldval),
  249.                    int struct_frame_offset,
  250.                    void (*value_changed_in_frame)
  251.                    (Lisp_Object specifier, struct frame *f,
  252.                     Lisp_Object oldval));
  253. extern void set_specifier_fallback (Lisp_Object specifier,
  254.                     Lisp_Object fallback);
  255. extern void recompute_all_cached_specifiers_in_window (struct window *w);
  256. extern void recompute_all_cached_specifiers_in_frame (struct frame *f);
  257.  
  258. extern void cleanup_specifiers (void);
  259. extern int finish_marking_specifiers (int (*obj_marked_p) (Lisp_Object),
  260.                       void (*markobj) (Lisp_Object));
  261. extern void prune_specifiers (int (*obj_marked_p) (Lisp_Object));
  262. extern void setup_device_initial_specifier_tags (struct device *d);
  263.  
  264. DECLARE_SPECIFIER_TYPE (generic);
  265. #define XGENERIC_SPECIFIER(x) XSPECIFIER_TYPE (x, generic)
  266. #define XSETGENERIC_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, generic)
  267. #define GENERIC_SPECIFIERP(x) SPECIFIER_TYPEP (x, generic)
  268. #define CHECK_GENERIC_SPECIFIER(x, i) CHECK_SPECIFIER_TYPE (x, i, generic)
  269.  
  270. DECLARE_SPECIFIER_TYPE (integer);
  271. #define XINTEGER_SPECIFIER(x) XSPECIFIER_TYPE (x, integer)
  272. #define XSETINTEGER_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, integer)
  273. #define INTEGER_SPECIFIERP(x) SPECIFIER_TYPEP (x, integer)
  274. #define CHECK_INTEGER_SPECIFIER(x, i) CHECK_SPECIFIER_TYPE (x, i, integer)
  275.  
  276. DECLARE_SPECIFIER_TYPE (natnum);
  277. #define XNATNUM_SPECIFIER(x) XSPECIFIER_TYPE (x, natnum)
  278. #define XSETNATNUM_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, natnum)
  279. #define NATNUM_SPECIFIERP(x) SPECIFIER_TYPEP (x, natnum)
  280. #define CHECK_NATNUM_SPECIFIER(x, i) CHECK_SPECIFIER_TYPE (x, i, natnum)
  281.  
  282. DECLARE_SPECIFIER_TYPE (boolean);
  283. #define XBOOLEAN_SPECIFIER(x) XSPECIFIER_TYPE (x, boolean)
  284. #define XSETBOOLEAN_SPECIFIER(x, p) XSETSPECIFIER_TYPE (x, p, boolean)
  285. #define BOOLEAN_SPECIFIERP(x) SPECIFIER_TYPEP (x, boolean)
  286. #define CHECK_BOOLEAN_SPECIFIER(x, i) CHECK_SPECIFIER_TYPE (x, i, boolean)
  287.  
  288. #endif /* _XEMACS_SPECIFIER_H_ */
  289.